gsk: Move gtk/gtkcairoblur.c to gsk/gskcairoblur.c
authorBenjamin Otte <otte@redhat.com>
Sun, 18 Dec 2016 20:45:15 +0000 (21:45 +0100)
committerBenjamin Otte <otte@redhat.com>
Tue, 20 Dec 2016 17:01:11 +0000 (18:01 +0100)
docs/reference/gtk/Makefile.am
gsk/Makefile.am
gsk/gskcairoblur.c [new file with mode: 0644]
gsk/gskcairoblurprivate.h [new file with mode: 0644]
gtk/Makefile.am
gtk/gtkcairoblur.c [deleted file]
gtk/gtkcairoblurprivate.h [deleted file]
gtk/gtkcssshadowsvalue.c
gtk/gtkcssshadowvalue.c
tests/Makefile.am
tests/blur-performance.c

index b8e240454196de28e69f00fec0108cb0e71182cb..300c5859e2abd819cd8997b44bacba0ecbae4c2d 100644 (file)
@@ -36,7 +36,6 @@ IGNORE_HFILES = \
        gtkbuilderprivate.h             \
        gtkbuiltiniconprivate.h         \
        gtkbuttonprivate.h              \
-       gtkcairoblurprivate.h           \
        gtkcellareaboxcontextprivate.h  \
        gtkcheckbuttonprivate.h         \
        gtkclipboardprivate.h           \
index 93480f6b8d702d1204184af783c567b33fb07268..8a7a5a36d781372c0099737ce31652b5ac031311 100644 (file)
@@ -60,6 +60,7 @@ gsk_public_source_h = \
        gsktypes.h
 gsk_private_source_h = \
        $(gsk_private_vulkan_source_h) \
+       gskcairoblurprivate.h \
        gskcairorendererprivate.h \
        gskdebugprivate.h \
        gskgldriverprivate.h \
@@ -80,6 +81,7 @@ gsk_public_source_c = \
        gsktexture.c
 gsk_private_source_c = \
        $(gsk_private_vulkan_source_c) \
+       gskcairoblur.c \
        gskcairorenderer.c \
        gskdebug.c \
        gskgldriver.c \
diff --git a/gsk/gskcairoblur.c b/gsk/gskcairoblur.c
new file mode 100644 (file)
index 0000000..0fcd1c6
--- /dev/null
@@ -0,0 +1,282 @@
+/* GSK - The GIMP Toolkit
+ *
+ * Copyright (C) 2014 Red Hat
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Library General Public License for more details.
+ *
+ * You should have received a copy of the GNU Library General Public
+ * License along with this library. If not, see <http://www.gnu.org/licenses/>.
+ *
+ * Written by:
+ *     Jasper St. Pierre <jstpierre@mecheye.net>
+ *     Owen Taylor <otaylor@redhat.com>
+ */
+
+#include "gskcairoblurprivate.h"
+
+#include <math.h>
+#include <string.h>
+
+/*
+ * Gets the size for a single box blur.
+ *
+ * Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
+ * approximating a Gaussian using box blurs.  This yields quite a good
+ * approximation for a Gaussian.  For more details, see:
+ * http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
+ */
+#define GAUSSIAN_SCALE_FACTOR ((3.0 * sqrt(2 * G_PI) / 4))
+
+#define get_box_filter_size(radius) ((int)(GAUSSIAN_SCALE_FACTOR * (radius)))
+
+/* Sadly, clang is picky about get_box_filter_size(2) not being a
+ * constant expression, thus we have to use precomputed values.
+ */
+#define BOX_FILTER_SIZE_2 3
+#define BOX_FILTER_SIZE_3 5
+#define BOX_FILTER_SIZE_4 7
+#define BOX_FILTER_SIZE_5 9
+#define BOX_FILTER_SIZE_6 11
+#define BOX_FILTER_SIZE_7 13
+#define BOX_FILTER_SIZE_8 15
+#define BOX_FILTER_SIZE_9 16
+#define BOX_FILTER_SIZE_10 18
+
+/* This applies a single box blur pass to a horizontal range of pixels;
+ * since the box blur has the same weight for all pixels, we can
+ * implement an efficient sliding window algorithm where we add
+ * in pixels coming into the window from the right and remove
+ * them when they leave the windw to the left.
+ *
+ * d is the filter width; for even d shift indicates how the blurred
+ * result is aligned with the original - does ' x ' go to ' yy' (shift=1)
+ * or 'yy ' (shift=-1)
+ */
+static void
+blur_xspan (guchar *row,
+            guchar *tmp_buffer,
+            int     row_width,
+            int     d,
+            int     shift)
+{
+  int offset;
+  int sum = 0;
+  int i;
+
+  if (d % 2 == 1)
+    offset = d / 2;
+  else
+    offset = (d - shift) / 2;
+
+  /* All the conditionals in here look slow, but the branches will
+   * be well predicted and there are enough different possibilities
+   * that trying to write this as a series of unconditional loops
+   * is hard and not an obvious win. The main slow down here seems
+   * to be the integer division per pixel; one possible optimization
+   * would be to accumulate into two 16-bit integer buffers and
+   * only divide down after all three passes. (SSE parallel implementation
+   * of the divide step is possible.)
+   */
+
+#define BLUR_ROW_KERNEL(D)                                      \
+  for (i = -(D) + offset; i < row_width + offset; i++)         \
+    {                                                           \
+      if (i >= 0 && i < row_width)                              \
+        sum += row[i];                                          \
+                                                                \
+      if (i >= offset)                                         \
+       {                                                       \
+         if (i >= (D))                                         \
+           sum -= row[i - (D)];                                \
+                                                                \
+         tmp_buffer[i - offset] = (sum + (D) / 2) / (D);       \
+       }                                                       \
+    }                                                          \
+  break;
+
+  /* We unroll the values for d for radius 2-10 to avoid a generic
+   * divide operation (not radius 1, because its a no-op) */
+  switch (d)
+    {
+    case BOX_FILTER_SIZE_2: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_2);
+    case BOX_FILTER_SIZE_3: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_3);
+    case BOX_FILTER_SIZE_4: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_4);
+    case BOX_FILTER_SIZE_5: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_5);
+    case BOX_FILTER_SIZE_6: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_6);
+    case BOX_FILTER_SIZE_7: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_7);
+    case BOX_FILTER_SIZE_8: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_8);
+    case BOX_FILTER_SIZE_9: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_9);
+    case BOX_FILTER_SIZE_10: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_10);
+    default: BLUR_ROW_KERNEL (d);
+    }
+
+  memcpy (row, tmp_buffer, row_width);
+}
+
+static void
+blur_rows (guchar *dst_buffer,
+           guchar *tmp_buffer,
+           int     buffer_width,
+           int     buffer_height,
+           int     d)
+{
+  int i;
+
+  for (i = 0; i < buffer_height; i++)
+    {
+      guchar *row = dst_buffer + i * buffer_width;
+
+      /* We want to produce a symmetric blur that spreads a pixel
+       * equally far to the left and right. If d is odd that happens
+       * naturally, but for d even, we approximate by using a blur
+       * on either side and then a centered blur of size d + 1.
+       * (technique also from the SVG specification)
+       */
+      if (d % 2 == 1)
+        {
+          blur_xspan (row, tmp_buffer, buffer_width, d, 0);
+          blur_xspan (row, tmp_buffer, buffer_width, d, 0);
+          blur_xspan (row, tmp_buffer, buffer_width, d, 0);
+        }
+      else
+        {
+          blur_xspan (row, tmp_buffer, buffer_width, d, 1);
+          blur_xspan (row, tmp_buffer, buffer_width, d, -1);
+          blur_xspan (row, tmp_buffer, buffer_width, d + 1, 0);
+        }
+    }
+}
+
+/* Swaps width and height.
+ */
+static void
+flip_buffer (guchar *dst_buffer,
+             guchar *src_buffer,
+             int     width,
+             int     height)
+{
+  /* Working in blocks increases cache efficiency, compared to reading
+   * or writing an entire column at once
+   */
+#define BLOCK_SIZE 16
+
+  int i0, j0;
+
+  for (i0 = 0; i0 < width; i0 += BLOCK_SIZE)
+    for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
+      {
+        int max_j = MIN(j0 + BLOCK_SIZE, height);
+        int max_i = MIN(i0 + BLOCK_SIZE, width);
+        int i, j;
+
+        for (i = i0; i < max_i; i++)
+          for (j = j0; j < max_j; j++)
+            dst_buffer[i * height + j] = src_buffer[j * width + i];
+      }
+#undef BLOCK_SIZE
+}
+
+static void
+_boxblur (guchar      *buffer,
+          int          width,
+          int          height,
+          int          radius,
+          GskBlurFlags flags)
+{
+  guchar *flipped_buffer;
+  int d = get_box_filter_size (radius);
+
+  flipped_buffer = g_malloc (width * height);
+
+  if (flags & GSK_BLUR_Y)
+    {
+      /* Step 1: swap rows and columns */
+      flip_buffer (flipped_buffer, buffer, width, height);
+
+      /* Step 2: blur rows (really columns) */
+      blur_rows (flipped_buffer, buffer, height, width, d);
+
+      /* Step 3: swap rows and columns */
+      flip_buffer (buffer, flipped_buffer, height, width);
+    }
+
+  if (flags & GSK_BLUR_X)
+    {
+      /* Step 4: blur rows */
+      blur_rows (buffer, flipped_buffer, width, height, d);
+    }
+
+  g_free (flipped_buffer);
+}
+
+/*
+ * _gsk_cairo_blur_surface:
+ * @surface: a cairo image surface.
+ * @radius: the blur radius.
+ *
+ * Blurs the cairo image surface at the given radius.
+ */
+void
+gsk_cairo_blur_surface (cairo_surface_t* surface,
+                        double           radius_d,
+                        GskBlurFlags     flags)
+{
+  int radius = radius_d;
+
+  g_return_if_fail (surface != NULL);
+  g_return_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE);
+  g_return_if_fail (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_A8);
+
+  /* The code doesn't actually do any blurring for radius 1, as it
+   * ends up with box filter size 1 */
+  if (radius <= 1)
+    return;
+
+  if ((flags & (GSK_BLUR_X|GSK_BLUR_Y)) == 0)
+    return;
+
+  /* Before we mess with the surface, execute any pending drawing. */
+  cairo_surface_flush (surface);
+
+  _boxblur (cairo_image_surface_get_data (surface),
+            cairo_image_surface_get_stride (surface),
+            cairo_image_surface_get_height (surface),
+            radius, flags);
+
+  /* Inform cairo we altered the surface contents. */
+  cairo_surface_mark_dirty (surface);
+}
+
+/*<private>
+ * gsk_cairo_blur_compute_pixels:
+ * @radius: the radius to compute the pixels for
+ *
+ * Computes the number of pixels necessary to extend an image in one
+ * direction to hold the image with shadow.
+ *
+ * This is just the number of pixels added by the blur radius, shadow
+ * offset and spread are not included.
+ *
+ * Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
+ * approximating a Gaussian using box blurs.  This yields quite a good
+ * approximation for a Gaussian.  Then we multiply this by 1.5 since our
+ * code wants the radius of the entire triple-box-blur kernel instead of
+ * the diameter of an individual box blur.  For more details, see:
+ * http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
+ * https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
+ */
+int
+gsk_cairo_blur_compute_pixels (double radius)
+{
+  return floor (radius * GAUSSIAN_SCALE_FACTOR * 1.5 + 0.5);
+}
+
diff --git a/gsk/gskcairoblurprivate.h b/gsk/gskcairoblurprivate.h
new file mode 100644 (file)
index 0000000..d723ca6
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2012 Canonical Ltd
+ *
+ * This  library is free  software; you can  redistribute it and/or
+ * modify it  under  the terms  of the  GNU Lesser  General  Public
+ * License  as published  by the Free  Software  Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed  in the hope that it will be useful,
+ * but  WITHOUT ANY WARRANTY; without even  the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License  along  with  this library;  if not,  write to  the Free
+ * Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
+ * MA 02110-1301, USA.
+ *
+ * Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
+ * Original code from Mirco Mueller <mirco.mueller@canonical.com>
+ *
+ */
+
+#ifndef _GSK_CAIRO_BLUR_H
+#define _GSK_CAIRO_BLUR_H
+
+#include <glib.h>
+#include <cairo.h>
+
+G_BEGIN_DECLS
+
+typedef enum {
+  GSK_BLUR_NONE = 0,
+  GSK_BLUR_X = 1<<0,
+  GSK_BLUR_Y = 1<<1,
+  GSK_BLUR_REPEAT = 1<<2
+} GskBlurFlags;
+
+void            gsk_cairo_blur_surface          (cairo_surface_t *surface,
+                                                 double           radius,
+                                                GskBlurFlags     flags);
+int             gsk_cairo_blur_compute_pixels   (double           radius);
+
+G_END_DECLS
+
+#endif /* _GSK_CAIRO_BLUR_H */
index c54aaffe2d2a4c31c4e36759fef3368917821969..2578e1f5f2e75796b31c907f4cd92cd51eb2d1d9 100644 (file)
@@ -377,7 +377,6 @@ gtk_private_h_sources =             \
        gtkbuilderprivate.h     \
        gtkbuiltiniconprivate.h \
        gtkbuttonprivate.h      \
-       gtkcairoblurprivate.h   \
        gtkcellareaboxcontextprivate.h  \
        gtkcheckbuttonprivate.h \
        gtkcheckmenuitemprivate.h       \
@@ -626,7 +625,6 @@ gtk_base_c_sources =                \
        gtkbuilder-menus.c      \
        gtkbuiltinicon.c        \
        gtkbutton.c             \
-       gtkcairoblur.c          \
        gtkcalendar.c           \
        gtkcellarea.c           \
        gtkcellareabox.c        \
diff --git a/gtk/gtkcairoblur.c b/gtk/gtkcairoblur.c
deleted file mode 100644 (file)
index 63b1a3e..0000000
+++ /dev/null
@@ -1,281 +0,0 @@
-/* GTK - The GIMP Toolkit
- *
- * Copyright (C) 2014 Red Hat
- *
- * This library is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Library General Public
- * License as published by the Free Software Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Library General Public License for more details.
- *
- * You should have received a copy of the GNU Library General Public
- * License along with this library. If not, see <http://www.gnu.org/licenses/>.
- *
- * Written by:
- *     Jasper St. Pierre <jstpierre@mecheye.net>
- *     Owen Taylor <otaylor@redhat.com>
- */
-
-#include "gtkcairoblurprivate.h"
-
-#include <math.h>
-#include <string.h>
-
-/*
- * Gets the size for a single box blur.
- *
- * Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
- * approximating a Gaussian using box blurs.  This yields quite a good
- * approximation for a Gaussian.  For more details, see:
- * http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
- * https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
- */
-#define GAUSSIAN_SCALE_FACTOR ((3.0 * sqrt(2 * G_PI) / 4))
-
-#define get_box_filter_size(radius) ((int)(GAUSSIAN_SCALE_FACTOR * (radius)))
-
-/* Sadly, clang is picky about get_box_filter_size(2) not being a
- * constant expression, thus we have to use precomputed values.
- */
-#define BOX_FILTER_SIZE_2 3
-#define BOX_FILTER_SIZE_3 5
-#define BOX_FILTER_SIZE_4 7
-#define BOX_FILTER_SIZE_5 9
-#define BOX_FILTER_SIZE_6 11
-#define BOX_FILTER_SIZE_7 13
-#define BOX_FILTER_SIZE_8 15
-#define BOX_FILTER_SIZE_9 16
-#define BOX_FILTER_SIZE_10 18
-
-/* This applies a single box blur pass to a horizontal range of pixels;
- * since the box blur has the same weight for all pixels, we can
- * implement an efficient sliding window algorithm where we add
- * in pixels coming into the window from the right and remove
- * them when they leave the windw to the left.
- *
- * d is the filter width; for even d shift indicates how the blurred
- * result is aligned with the original - does ' x ' go to ' yy' (shift=1)
- * or 'yy ' (shift=-1)
- */
-static void
-blur_xspan (guchar *row,
-            guchar *tmp_buffer,
-            int     row_width,
-            int     d,
-            int     shift)
-{
-  int offset;
-  int sum = 0;
-  int i;
-
-  if (d % 2 == 1)
-    offset = d / 2;
-  else
-    offset = (d - shift) / 2;
-
-  /* All the conditionals in here look slow, but the branches will
-   * be well predicted and there are enough different possibilities
-   * that trying to write this as a series of unconditional loops
-   * is hard and not an obvious win. The main slow down here seems
-   * to be the integer division per pixel; one possible optimization
-   * would be to accumulate into two 16-bit integer buffers and
-   * only divide down after all three passes. (SSE parallel implementation
-   * of the divide step is possible.)
-   */
-
-#define BLUR_ROW_KERNEL(D)                                      \
-  for (i = -(D) + offset; i < row_width + offset; i++)         \
-    {                                                           \
-      if (i >= 0 && i < row_width)                              \
-        sum += row[i];                                          \
-                                                                \
-      if (i >= offset)                                         \
-       {                                                       \
-         if (i >= (D))                                         \
-           sum -= row[i - (D)];                                \
-                                                                \
-         tmp_buffer[i - offset] = (sum + (D) / 2) / (D);       \
-       }                                                       \
-    }                                                          \
-  break;
-
-  /* We unroll the values for d for radius 2-10 to avoid a generic
-   * divide operation (not radius 1, because its a no-op) */
-  switch (d)
-    {
-    case BOX_FILTER_SIZE_2: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_2);
-    case BOX_FILTER_SIZE_3: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_3);
-    case BOX_FILTER_SIZE_4: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_4);
-    case BOX_FILTER_SIZE_5: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_5);
-    case BOX_FILTER_SIZE_6: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_6);
-    case BOX_FILTER_SIZE_7: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_7);
-    case BOX_FILTER_SIZE_8: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_8);
-    case BOX_FILTER_SIZE_9: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_9);
-    case BOX_FILTER_SIZE_10: BLUR_ROW_KERNEL (BOX_FILTER_SIZE_10);
-    default: BLUR_ROW_KERNEL (d);
-    }
-
-  memcpy (row, tmp_buffer, row_width);
-}
-
-static void
-blur_rows (guchar *dst_buffer,
-           guchar *tmp_buffer,
-           int     buffer_width,
-           int     buffer_height,
-           int     d)
-{
-  int i;
-
-  for (i = 0; i < buffer_height; i++)
-    {
-      guchar *row = dst_buffer + i * buffer_width;
-
-      /* We want to produce a symmetric blur that spreads a pixel
-       * equally far to the left and right. If d is odd that happens
-       * naturally, but for d even, we approximate by using a blur
-       * on either side and then a centered blur of size d + 1.
-       * (technique also from the SVG specification)
-       */
-      if (d % 2 == 1)
-        {
-          blur_xspan (row, tmp_buffer, buffer_width, d, 0);
-          blur_xspan (row, tmp_buffer, buffer_width, d, 0);
-          blur_xspan (row, tmp_buffer, buffer_width, d, 0);
-        }
-      else
-        {
-          blur_xspan (row, tmp_buffer, buffer_width, d, 1);
-          blur_xspan (row, tmp_buffer, buffer_width, d, -1);
-          blur_xspan (row, tmp_buffer, buffer_width, d + 1, 0);
-        }
-    }
-}
-
-/* Swaps width and height.
- */
-static void
-flip_buffer (guchar *dst_buffer,
-             guchar *src_buffer,
-             int     width,
-             int     height)
-{
-  /* Working in blocks increases cache efficiency, compared to reading
-   * or writing an entire column at once
-   */
-#define BLOCK_SIZE 16
-
-  int i0, j0;
-
-  for (i0 = 0; i0 < width; i0 += BLOCK_SIZE)
-    for (j0 = 0; j0 < height; j0 += BLOCK_SIZE)
-      {
-        int max_j = MIN(j0 + BLOCK_SIZE, height);
-        int max_i = MIN(i0 + BLOCK_SIZE, width);
-        int i, j;
-
-        for (i = i0; i < max_i; i++)
-          for (j = j0; j < max_j; j++)
-            dst_buffer[i * height + j] = src_buffer[j * width + i];
-      }
-#undef BLOCK_SIZE
-}
-
-static void
-_boxblur (guchar      *buffer,
-          int          width,
-          int          height,
-          int          radius,
-          GtkBlurFlags flags)
-{
-  guchar *flipped_buffer;
-  int d = get_box_filter_size (radius);
-
-  flipped_buffer = g_malloc (width * height);
-
-  if (flags & GTK_BLUR_Y)
-    {
-      /* Step 1: swap rows and columns */
-      flip_buffer (flipped_buffer, buffer, width, height);
-
-      /* Step 2: blur rows (really columns) */
-      blur_rows (flipped_buffer, buffer, height, width, d);
-
-      /* Step 3: swap rows and columns */
-      flip_buffer (buffer, flipped_buffer, height, width);
-    }
-
-  if (flags & GTK_BLUR_X)
-    {
-      /* Step 4: blur rows */
-      blur_rows (buffer, flipped_buffer, width, height, d);
-    }
-
-  g_free (flipped_buffer);
-}
-
-/*
- * _gtk_cairo_blur_surface:
- * @surface: a cairo image surface.
- * @radius: the blur radius.
- *
- * Blurs the cairo image surface at the given radius.
- */
-void
-_gtk_cairo_blur_surface (cairo_surface_t* surface,
-                         double           radius_d,
-                         GtkBlurFlags     flags)
-{
-  int radius = radius_d;
-
-  g_return_if_fail (surface != NULL);
-  g_return_if_fail (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_IMAGE);
-  g_return_if_fail (cairo_image_surface_get_format (surface) == CAIRO_FORMAT_A8);
-
-  /* The code doesn't actually do any blurring for radius 1, as it
-   * ends up with box filter size 1 */
-  if (radius <= 1)
-    return;
-
-  if ((flags & (GTK_BLUR_X|GTK_BLUR_Y)) == 0)
-    return;
-
-  /* Before we mess with the surface, execute any pending drawing. */
-  cairo_surface_flush (surface);
-
-  _boxblur (cairo_image_surface_get_data (surface),
-            cairo_image_surface_get_stride (surface),
-            cairo_image_surface_get_height (surface),
-            radius, flags);
-
-  /* Inform cairo we altered the surface contents. */
-  cairo_surface_mark_dirty (surface);
-}
-
-/*
- * _gtk_cairo_blur_compute_pixels:
- * @radius: the radius to compute the pixels for
- *
- * Computes the number of pixels necessary to extend an image in one
- * direction to hold the image with shadow.
- *
- * This is just the number of pixels added by the blur radius, shadow
- * offset and spread are not included.
- *
- * Much of this, the 3 * sqrt(2 * pi) / 4, is the known value for
- * approximating a Gaussian using box blurs.  This yields quite a good
- * approximation for a Gaussian.  Then we multiply this by 1.5 since our
- * code wants the radius of the entire triple-box-blur kernel instead of
- * the diameter of an individual box blur.  For more details, see:
- * http://www.w3.org/TR/SVG11/filters.html#feGaussianBlurElement
- * https://bugzilla.mozilla.org/show_bug.cgi?id=590039#c19
- */
-int
-_gtk_cairo_blur_compute_pixels (double radius)
-{
-  return floor (radius * GAUSSIAN_SCALE_FACTOR * 1.5 + 0.5);
-}
diff --git a/gtk/gtkcairoblurprivate.h b/gtk/gtkcairoblurprivate.h
deleted file mode 100644 (file)
index 68126d3..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-/*
- * Copyright (C) 2012 Canonical Ltd
- *
- * This  library is free  software; you can  redistribute it and/or
- * modify it  under  the terms  of the  GNU Lesser  General  Public
- * License  as published  by the Free  Software  Foundation; either
- * version 2 of the License, or (at your option) any later version.
- *
- * This library is distributed  in the hope that it will be useful,
- * but  WITHOUT ANY WARRANTY; without even  the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License  along  with  this library;  if not,  write to  the Free
- * Software Foundation, Inc., 51  Franklin St, Fifth Floor, Boston,
- * MA 02110-1301, USA.
- *
- * Authored by Andrea Cimitan <andrea.cimitan@canonical.com>
- * Original code from Mirco Mueller <mirco.mueller@canonical.com>
- *
- */
-
-#ifndef _GTK_CAIRO_BLUR_H
-#define _GTK_CAIRO_BLUR_H
-
-#include <glib.h>
-#include <cairo.h>
-
-G_BEGIN_DECLS
-
-typedef enum {
-  GTK_BLUR_NONE = 0,
-  GTK_BLUR_X = 1<<0,
-  GTK_BLUR_Y = 1<<1,
-  GTK_BLUR_REPEAT = 1<<2
-} GtkBlurFlags;
-
-void            _gtk_cairo_blur_surface         (cairo_surface_t *surface,
-                                                 double           radius,
-                                                GtkBlurFlags     flags);;
-int             _gtk_cairo_blur_compute_pixels  (double           radius);
-
-G_END_DECLS
-
-#endif /* _GTK_CAIRO_BLUR_H */
index bba53ffead79e438bac3d2dc6ed63e0a134dbdf9..c7037a7a3e1817c919e698b3cc23a6b497050a3f 100644 (file)
@@ -23,7 +23,6 @@
 
 #include <math.h>
 
-#include "gtkcairoblurprivate.h"
 #include "gtkcssshadowvalueprivate.h"
 
 #include <string.h>
index 6edd51aa227c4697142dc9905f1e956474b373e1..86b30296dad56c848c05cf2552c31a3b55294081 100644 (file)
@@ -21,7 +21,6 @@
 
 #include "gtkcssshadowvalueprivate.h"
 
-#include "gtkcairoblurprivate.h"
 #include "gtkcsscolorvalueprivate.h"
 #include "gtkcssnumbervalueprivate.h"
 #include "gtkcssrgbavalueprivate.h"
@@ -30,6 +29,7 @@
 #include "gtkrenderprivate.h"
 #include "gtkpango.h"
 
+#include "gsk/gskcairoblurprivate.h"
 #include "gsk/gskroundedrectprivate.h"
 
 #include <math.h>
@@ -329,15 +329,15 @@ static const cairo_user_data_key_t original_cr_key;
 static cairo_t *
 gtk_css_shadow_value_start_drawing (const GtkCssValue *shadow,
                                     cairo_t           *cr,
-                                    GtkBlurFlags       blur_flags)
+                                    GskBlurFlags       blur_flags)
 {
   cairo_rectangle_int_t clip_rect;
   cairo_surface_t *surface;
   cairo_t *blur_cr;
   gdouble radius, clip_radius;
   gdouble x_scale, y_scale;
-  gboolean blur_x = (blur_flags & GTK_BLUR_X) != 0;
-  gboolean blur_y = (blur_flags & GTK_BLUR_Y) != 0;
+  gboolean blur_x = (blur_flags & GSK_BLUR_X) != 0;
+  gboolean blur_y = (blur_flags & GSK_BLUR_Y) != 0;
 
   if (!needs_blur (shadow))
     return cr;
@@ -345,12 +345,12 @@ gtk_css_shadow_value_start_drawing (const GtkCssValue *shadow,
   gdk_cairo_get_clip_rectangle (cr, &clip_rect);
 
   radius = _gtk_css_number_value_get (shadow->radius, 0);
-  clip_radius = _gtk_cairo_blur_compute_pixels (radius);
+  clip_radius = gsk_cairo_blur_compute_pixels (radius);
 
   x_scale = y_scale = 1;
   cairo_surface_get_device_scale (cairo_get_target (cr), &x_scale, &y_scale);
 
-  if (blur_flags & GTK_BLUR_REPEAT)
+  if (blur_flags & GSK_BLUR_REPEAT)
     {
       if (!blur_x)
         clip_rect.width = 1;
@@ -399,7 +399,7 @@ mask_surface_repeat (cairo_t         *cr,
 static cairo_t *
 gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow,
                                      cairo_t           *cr,
-                                     GtkBlurFlags       blur_flags)
+                                     GskBlurFlags       blur_flags)
 {
   gdouble radius;
   cairo_t *original_cr;
@@ -418,10 +418,10 @@ gtk_css_shadow_value_finish_drawing (const GtkCssValue *shadow,
   x_scale = 1;
   cairo_surface_get_device_scale (cairo_get_target (cr), &x_scale, NULL);
 
-  _gtk_cairo_blur_surface (surface, x_scale * radius, blur_flags);
+  gsk_cairo_blur_surface (surface, x_scale * radius, blur_flags);
 
   gdk_cairo_set_source_rgba (original_cr, _gtk_css_rgba_value_get_rgba (shadow->color));
-  if (blur_flags & GTK_BLUR_REPEAT)
+  if (blur_flags & GSK_BLUR_REPEAT)
     mask_surface_repeat (original_cr, surface);
   else
     cairo_mask_surface (original_cr, surface, 0, 0);
@@ -478,7 +478,7 @@ make_blurred_pango_surface (cairo_t           *existing_cr,
   radius = _gtk_css_number_value_get (shadow->radius, 0);
 
   pango_layout_get_pixel_extents (layout, &ink_rect, NULL);
-  clip_radius = _gtk_cairo_blur_compute_pixels (radius);
+  clip_radius = gsk_cairo_blur_compute_pixels (radius);
   x_scale = y_scale = 1;
   cairo_surface_get_device_scale (cairo_get_target (existing_cr), &x_scale, &y_scale);
 
@@ -491,7 +491,7 @@ make_blurred_pango_surface (cairo_t           *existing_cr,
   cr = cairo_create (surface);
   cairo_move_to (cr, 0, 0);
   _gtk_pango_fill_layout (cr, layout);
-  _gtk_cairo_blur_surface (surface, radius * x_scale, GTK_BLUR_X | GTK_BLUR_Y);
+  gsk_cairo_blur_surface (surface, radius * x_scale, GSK_BLUR_X | GSK_BLUR_Y);
 
   cairo_destroy (cr);
 
@@ -586,14 +586,14 @@ _gtk_css_shadow_value_paint_icon (const GtkCssValue *shadow,
   pattern = cairo_pattern_reference (cairo_get_source (cr));
 
   gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
-  cr = gtk_css_shadow_value_start_drawing (shadow, cr, GTK_BLUR_X | GTK_BLUR_Y);
+  cr = gtk_css_shadow_value_start_drawing (shadow, cr, GSK_BLUR_X | GSK_BLUR_Y);
 
   cairo_translate (cr,
                    _gtk_css_number_value_get (shadow->hoffset, 0),
                    _gtk_css_number_value_get (shadow->voffset, 0));
   cairo_mask (cr, pattern);
 
-  cr = gtk_css_shadow_value_finish_drawing (shadow, cr, GTK_BLUR_X | GTK_BLUR_Y);
+  cr = gtk_css_shadow_value_finish_drawing (shadow, cr, GSK_BLUR_X | GSK_BLUR_Y);
 
   cairo_restore (cr);
   cairo_pattern_destroy (pattern);
@@ -615,7 +615,7 @@ gtk_css_shadow_value_get_extents (const GtkCssValue *shadow,
 
   spread = _gtk_css_number_value_get (shadow->spread, 0);
   radius = _gtk_css_number_value_get (shadow->radius, 0);
-  clip_radius = _gtk_cairo_blur_compute_pixels (radius);
+  clip_radius = gsk_cairo_blur_compute_pixels (radius);
   hoffset = _gtk_css_number_value_get (shadow->hoffset, 0);
   voffset = _gtk_css_number_value_get (shadow->voffset, 0);
 
@@ -639,7 +639,7 @@ draw_shadow (const GtkCssValue   *shadow,
             cairo_t             *cr,
             GskRoundedRect      *box,
             GskRoundedRect      *clip_box,
-            GtkBlurFlags         blur_flags)
+            GskBlurFlags         blur_flags)
 {
   cairo_t *shadow_cr;
   gboolean do_blur;
@@ -648,7 +648,7 @@ draw_shadow (const GtkCssValue   *shadow,
     return;
 
   gdk_cairo_set_source_rgba (cr, _gtk_css_rgba_value_get_rgba (shadow->color));
-  do_blur = (blur_flags & (GTK_BLUR_X | GTK_BLUR_Y)) != 0;
+  do_blur = (blur_flags & (GSK_BLUR_X | GSK_BLUR_Y)) != 0;
   if (do_blur)
     shadow_cr = gtk_css_shadow_value_start_drawing (shadow, cr, blur_flags);
   else
@@ -710,7 +710,7 @@ draw_shadow_corner (const GtkCssValue     *shadow,
   gboolean overlapped;
 
   radius = _gtk_css_number_value_get (shadow->radius, 0);
-  clip_radius = _gtk_cairo_blur_compute_pixels (radius);
+  clip_radius = gsk_cairo_blur_compute_pixels (radius);
 
   overlapped = FALSE;
   if (corner == GSK_CORNER_TOP_LEFT || corner == GSK_CORNER_BOTTOM_LEFT)
@@ -771,7 +771,7 @@ draw_shadow_corner (const GtkCssValue     *shadow,
     {
       /* Fall back to generic path if inset or if the corner radius
          runs into each other */
-      draw_shadow (shadow, cr, box, clip_box, GTK_BLUR_X | GTK_BLUR_Y);
+      draw_shadow (shadow, cr, box, clip_box, GSK_BLUR_X | GSK_BLUR_Y);
       return;
     }
 
@@ -812,7 +812,7 @@ draw_shadow_corner (const GtkCssValue     *shadow,
       corner_box.corner[0] = box->corner[corner];
       gsk_rounded_rect_path (&corner_box, mask_cr);
       cairo_fill (mask_cr);
-      _gtk_cairo_blur_surface (mask, radius, GTK_BLUR_X | GTK_BLUR_Y);
+      gsk_cairo_blur_surface (mask, radius, GSK_BLUR_X | GSK_BLUR_Y);
       cairo_destroy (mask_cr);
       g_hash_table_insert (corner_mask_cache, g_memdup (&key, sizeof (key)), mask);
     }
@@ -835,16 +835,16 @@ draw_shadow_side (const GtkCssValue   *shadow,
                   GtkCssSide           side,
                   cairo_rectangle_int_t *drawn_rect)
 {
-  GtkBlurFlags blur_flags = GTK_BLUR_REPEAT;
+  GskBlurFlags blur_flags = GSK_BLUR_REPEAT;
   gdouble radius, clip_radius;
   int x1, x2, y1, y2;
 
   radius = _gtk_css_number_value_get (shadow->radius, 0);
-  clip_radius = _gtk_cairo_blur_compute_pixels (radius);
+  clip_radius = gsk_cairo_blur_compute_pixels (radius);
 
   if (side == GTK_CSS_TOP || side == GTK_CSS_BOTTOM)
     {
-      blur_flags |= GTK_BLUR_Y;
+      blur_flags |= GSK_BLUR_Y;
       x1 = floor (box->bounds.origin.x - clip_radius);
       x2 = ceil (box->bounds.origin.x + box->bounds.size.width + clip_radius);
     }
@@ -861,7 +861,7 @@ draw_shadow_side (const GtkCssValue   *shadow,
 
   if (side == GTK_CSS_LEFT || side == GTK_CSS_RIGHT)
     {
-      blur_flags |= GTK_BLUR_X;
+      blur_flags |= GSK_BLUR_X;
       y1 = floor (box->bounds.origin.y - clip_radius);
       y2 = ceil (box->bounds.origin.y + box->bounds.size.height + clip_radius);
     }
@@ -910,7 +910,7 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue   *shadow,
 
   spread = _gtk_css_number_value_get (shadow->spread, 0);
   radius = _gtk_css_number_value_get (shadow->radius, 0);
-  clip_radius = _gtk_cairo_blur_compute_pixels (radius);
+  clip_radius = gsk_cairo_blur_compute_pixels (radius);
   x = _gtk_css_number_value_get (shadow->hoffset, 0);
   y = _gtk_css_number_value_get (shadow->voffset, 0);
 
@@ -943,7 +943,7 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue   *shadow,
   gsk_rounded_rect_shrink (&clip_box, -clip_radius, -clip_radius, -clip_radius, -clip_radius);
 
   if (!needs_blur (shadow))
-    draw_shadow (shadow, cr, &box, &clip_box, GTK_BLUR_NONE);
+    draw_shadow (shadow, cr, &box, &clip_box, GSK_BLUR_NONE);
   else
     {
       int i;
@@ -1014,7 +1014,7 @@ _gtk_css_shadow_value_paint_box (const GtkCssValue   *shadow,
       cairo_save (cr);
       gdk_cairo_region (cr, remaining);
       cairo_clip (cr);
-      draw_shadow (shadow, cr, &box, &clip_box, GTK_BLUR_NONE);
+      draw_shadow (shadow, cr, &box, &clip_box, GSK_BLUR_NONE);
       cairo_restore (cr);
 
       cairo_region_destroy (remaining);
index 8b7b7468036e41a8837102695b68d1df84c192f6..943329d88ce857e5dc980ed8c33bf817cb8c7e66 100644 (file)
@@ -290,7 +290,7 @@ scrolling_performance_SOURCES = \
 
 blur_performance_SOURCES = \
        blur-performance.c      \
-       ../gtk/gtkcairoblur.c
+       ../gsk/gskcairoblur.c
 
 video_timer_SOURCES =  \
        video-timer.c   \
index a99e5cd00dd6f974aa7723712df70fbec9134779..c69a131f77382bc534c9166fd96f8ad4ad108817 100644 (file)
@@ -1,6 +1,6 @@
 /* -*- mode: C; c-basic-offset: 2; indent-tabs-mode: nil; -*- */
 
-#include <gtk/gtkcairoblurprivate.h>
+#include <gsk/gskcairoblurprivate.h>
 
 static void
 init_surface (cairo_t *cr)
@@ -41,7 +41,7 @@ main (int argc, char **argv)
        {
          init_surface (cr);
          g_timer_start (timer);
-         _gtk_cairo_blur_surface (surface, i, GTK_BLUR_X | GTK_BLUR_Y);
+         gsk_cairo_blur_surface (surface, i, GSK_BLUR_X | GSK_BLUR_Y);
          msec = g_timer_elapsed (timer, NULL) * 1000;
          if (j == 1)
            g_print ("Radius %2d: %.2f msec, %.2f kpixels/msec:\n", i, msec, size*size/(msec*1000));